package org.persistente.manipula.mapeamento;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Classe que mapeia classes para entidade de banco de dados.
 */
public abstract class MapaObjetoRelacional<T> {


    /**
     * Campos que não fazem parte de chave primária.
     */
    private ArrayList<CampoAbstrato> naoChaves = new ArrayList<CampoAbstrato>();

    /**
     * Todos os campos da entidade.
     */
    private ArrayList<CampoAbstrato> campos = new ArrayList<CampoAbstrato>();


    /**
     * Campos que fazem parte da chave primária da entidade.
     */
    private ArrayList<CampoAbstrato> chaves = new ArrayList<CampoAbstrato>();

    private Map<String, CampoAbstrato> indice = new HashMap<String, CampoAbstrato>();


    private String nomeEntidade;

    /**
     * Constrói um novo mapa com o nome da entidade.
     * @param nomeEntidade Nome da entidade.
     */
    public MapaObjetoRelacional(String nomeEntidade) {
        this.nomeEntidade = nomeEntidade;
    }

    /**
     * Singleton. As subclasses devem implementar esse método.
     * @return Instância única de mapeamento.
     */
    //public static MapaObjetoRelacional getInstance();

    /**
     * Recupera o nome da entidade.
     * @return Nome da entidade.
     */
    public String getNomeEntidade(){
        return nomeEntidade;
    }

    /**
     * Adiciona um novo par atributo/campo.
     * @param campo Informações de um atributo e seu respectivo campo.
     */
    public void campo(CampoAbstrato campo){
        naoChaves.add(campo);
        campos.add(campo);
        indice.put(campo.getNome(), campo);
    }

    /**
     * Adiciona um novo par atributo/campo como chave primária.
     * @param campo Informações de um atributo e seu respectivo campo.
     */
    public void chave(CampoAbstrato campo){
        campos.add(campo);
        chaves.add(campo);
        indice.put(campo.getNome(), campo);
    }


    /**
     * Recupera todos os campos.
     * @return Campos da entidade.
     */
    public List<CampoAbstrato> getCampos() {
        return campos;
    }

    /**
     * Retorna os campos pertencentes à chave primária da entidade.
     * @return Chave primária.
     */
    public List<CampoAbstrato> getChaves() {
        return chaves;
    }

    /**
     * Recupera os campos que não pertencem à chave primária da entidade.
     * @return Campos que não fazem parte da chave primária.
     */
    public List<CampoAbstrato> getNaoChaves() {
        return naoChaves;
    }

    public CampoAbstrato getCampo(String nome){
        return indice.get(nome);
    }
    
}
